package main

import (
	"common/version"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type PkgReleaseReq struct {
	Arch     string `json:"arch" form:"arch" binding:"required"`
	Os       string `json:"os" form:"os" binding:"required"`
	Version  string `json:"version" form:"version" binding:"required"`
	CommitId string `json:"commit_id" form:"commit_id" binding:"required"`
	Gray     int    `json:"gray" form:"gray" binding:"omitempty,min=0,max=99"`
	Env      string `json:"env" form:"env" binding:"required,oneof=prod dev test"`
	Release  bool   `json:"release" form:"release" binding:"omitempty"`
}

func (s *Server) release(ctx *gin.Context) {
	var err error
	defer func() {
		if err != nil {
			s.errorJson(ctx, err)
		}
	}()
	fh, err := ctx.FormFile("file")
	if err != nil {
		return
	}
	req := PkgReleaseReq{}
	err = ctx.Bind(&req)
	if err != nil {
		return
	}
	ver, err := version.FromString(req.Version)
	if err != nil {
		return
	}
	pkgItem := PkgItem{
		Version:  ver,
		CommitId: req.CommitId,
		Arch:     req.Arch,
		Os:       req.Os,
		Env:      req.Env,
		Gray:     req.Gray,
		Md5:      fh.Filename,
		//PkgFullPath: filepath.Join(s.config.PkgRoot, fh.Filename),
		//PkgAddress:  fmt.Sprintf("%s/pkg/%s", strings.TrimSuffix(s.config.BaseUrl, "/"), strings.TrimPrefix(fh.Filename, "/")),
		Size:      fh.Size,
		CreatedAt: time.Now(),
		UUID:      uuid.New().String(),
	}
	// 计算md5
	fp, err := fh.Open()
	if err != nil {
	}
	defer fp.Close()
	h := md5.New()
	_, _ = io.Copy(h, fp)
	pkgItem.Md5 = hex.EncodeToString(h.Sum(nil))
	//文件名拼上md5
	pkgName := fmt.Sprintf("%s.%s%s", strings.TrimSuffix(fh.Filename, filepath.Ext(fh.Filename)), pkgItem.Md5, filepath.Ext(fh.Filename))
	pkgItem.PkgFullPath = filepath.Join(s.config.PkgRoot, pkgName)
	pkgItem.DownloadUrl = fmt.Sprintf("%s/pkg/%s", strings.TrimSuffix(s.config.BaseUrl, "/"), strings.TrimPrefix(pkgName, "/"))

	//保存文件
	err = ctx.SaveUploadedFile(fh, pkgItem.PkgFullPath)
	if err != nil {
		return
	}

	err = s.pkgReleaseLog.Add(&pkgItem)
	if err != nil {
		return
	}
	//发布
	if req.Release {
		err = s.pkgList.release(&pkgItem)
		if err != nil {
			return
		}
	}
	s.successJson(ctx, pkgItem)
}

func (s *Server) download(ctx *gin.Context) {
	var err error
	defer func() {
		if err != nil {
			_ = ctx.AbortWithError(400, err)
			return
		}
	}()
	pkg := filepath.Join(s.config.PkgRoot, ctx.Param("file"))
	fi, err := os.Stat(pkg)
	if err != nil {
		return
	}
	if fi.IsDir() {
		err = errors.New("is dir")
		return
	}
	fp, err := os.Open(pkg)
	if err != nil {
		return
	}
	ctx.Header("Content-Type", "application/zip")
	ctx.Header("Accept-Length", fmt.Sprintf("%d", fi.Size()))
	_, err = io.Copy(ctx.Writer, fp)
	if err != nil {
		return
	}
}
